package edu.pku.sei.mte.compositetrans.flow;

import java.util.Map;

import org.eclipse.emf.ecore.resource.Resource;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import agg.xt_basis.GraGra;
import agg.xt_basis.TypeException;
import edu.pku.sei.mte.compositetrans.CompositeTController;
import edu.pku.sei.mte.compositetrans.TResult;
import edu.pku.sei.mte.mtemodel.model.MModelGraph;
import edu.pku.sei.mte.mtemodel.mtmodel.ModelType;
import edu.pku.sei.mte.mtemodel.mtmodel.Transformation;
import edu.pku.sei.mte.runtime.rulebased.RBTEnvironment;
import edu.pku.sei.mte.serialization.EcoreTransformationLoader;
import edu.pku.sei.mte.serialization.EcoreXMILoader;
import edu.pku.sei.mte.transformation.VisitorFactory;
import edu.pku.sei.mte.utilities.ModelFormat;
import edu.pku.sei.mte.utilities.Utility;

public class TDecisionNode extends DecisionNode<Transformation> {

	protected CompositeTController container = null;
	protected String dependon = null;
	@Override
	public boolean execute() throws Exception{
		RBTEnvironment env = new RBTEnvironment(Utility.cur_env);
		env.setTransformation(condition);
		ModelType mt = condition.getModelTypes().get(0);
		TResult res = container.getTController(dependon).transform();
		env.getModelCollection().put(mt, getPKUMTModel(res, mt));
		Object obj = condition.accept(VisitorFactory.INSTANCE.getCheckConditionVisitor(env));
		if(obj instanceof Boolean){
			decision = (Boolean) obj;
			isSucceed = true;
		}else isSucceed = false;
		return isSucceed;
	}

	
	private MModelGraph getPKUMTModel(TResult result, ModelType type){
		if(result.modelFormat == ModelFormat.GGX){
			try {
				return Utility.GGX2PKUMT((GraGra) result.targetModel, type.getTypeGraph());
			} catch (TypeException e) {
				e.printStackTrace();
			}
		}
		else if(result.modelFormat == ModelFormat.PKUMT){
			return (MModelGraph) result.targetModel;
		}else if(result.modelFormat == ModelFormat.EMF){
			EcoreXMILoader loader = new EcoreXMILoader();
			return loader.load(type.getName(), (Resource)result.targetModel);
		}
		return null;
	}
	@Override
	public void load(Element e, Map<Integer, FlowNode> FlowNodesMap) {
		super.load(e, FlowNodesMap);
		NodeList nl = e.getChildNodes();
		for(int i=0;i<nl.getLength();i++){
			Node n = nl.item(i);
			if(n.getNodeType()!=Node.ELEMENT_NODE)
				continue;
			Element ee = (Element) n;
			if(ee.getTagName().equals("condition")){
				dependon = ee.getAttribute("dependon");
				EcoreTransformationLoader transLoader = new EcoreTransformationLoader();
				condition = transLoader.load(Utility.loadXML(ee.getAttribute("file")));
			}
		}
	}

	public CompositeTController getContainer() {
		return container;
	}

	public void setContainer(CompositeTController container) {
		this.container = container;
	}
}
